home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / icons / clrbut.zip / PDSCNTL.ZIP / PDSCNTL.C < prev    next >
Text File  |  1991-01-21  |  39KB  |  1,155 lines

  1. /*
  2.  * PDSCNTL -- Dialog Editor / Custom Controls
  3.  *            Copyright 1991, Professional Development Svcs, Dennis Cook
  4.  *
  5.  */
  6.  
  7. #include <string.h>
  8. #include <windows.h>
  9. #include <custcntl.h>
  10. #include "pdscntl.h"
  11. #include "clrbuttn.h"
  12.  
  13. /* Function Prototypes  */
  14.  
  15. void lstrncpy(LPSTR lpDest, LPSTR lpSrc, int n);
  16. BOOL FAR PASCAL DrawLabel(HDC hDC, LPSTR lpLabelText, int nCount);   
  17. void ShowButtonDown(HANDLE hWnd);
  18. void ShowButtonUp(HANDLE hWnd);
  19.  
  20. /* internal ColorButton function prototypes */
  21.  
  22. BOOL FAR PASCAL    ColorButtonDlgFn( HWND, WORD, WORD, LONG );
  23. LONG FAR PASCAL    ColorButtonWndFn( HWND, WORD, WORD, LONG );
  24.  
  25. /* global static variables */
  26.  
  27. HANDLE           hLibData;
  28. HANDLE           hLibInstance;
  29. LPFNSTRTOID      lpfnVerId;
  30. LPFNIDTOSTR      lpfnIdStr;
  31.  
  32. /* string for property lists */
  33. #define    IDFNLO                  "lpfnIdFnLo"
  34. #define    IDFNHI                  "lpfnIdFnHi"
  35.  
  36. /* general custom control definitions */
  37.  
  38. #define    ID                        GetWindowWord( hWnd, GWW_ID )
  39. #define    PARENT                    GetWindowWord( hWnd, GWW_HWNDPARENT )
  40. #define    INSTANCE                  GetWindowWord( hWnd, GWW_HINSTANCE )
  41.  
  42. #define    COLORBUTTONCLASS        "ColorButton"
  43.  
  44. /* ColorButton specific definitions */
  45.  
  46. #define  LABEL_EXTRA_SPACE 12
  47. #define  LABEL_LEN_OFFSET 8
  48. #define  LABEL_TEXT_OFFSET 10
  49.  
  50. #define    COLORBUTTON_EXTRA     24
  51.  
  52. #define    STRIP_BAD_DT_FLAG   0xFB7F
  53.  
  54. #define    BUTTONISDOWN_FLAG   0x0001
  55. #define    BUTTONINFOCUS_FLAG  0x0002
  56. #define    USENORMALTEXT_FLAG  0x0004
  57. #define    CAPTUREON_FLAG      0x0008
  58. #define    MKCNTLON_FLAG       0x0010
  59.  
  60. #define    BUTTONISUP_FLAG     0xFFFE
  61. #define    BUTTONNOFOCUS_FLAG  0xFFFD
  62. #define    USEGRAYEDTEXT_FLAG  0xFFFB
  63. #define    CAPTUREOFF_FLAG     0xFFF7
  64. #define    MKCNTLOFF_FLAG      0xFFEF
  65.  
  66. #define    FACEBRUSH             GetWindowWord( hWnd, 0 )
  67. #define    SHADOWBRUSH           GetWindowWord( hWnd, 2 )
  68. #define    HILITEBRUSH           GetWindowWord( hWnd, 4 )
  69. #define    LABELRGN              GetWindowWord( hWnd, 6 )
  70. #define    SHADOWRGN             GetWindowWord( hWnd, 8 )
  71. #define    HILITERGN             GetWindowWord( hWnd, 10 )
  72. #define    NORMALTEXTRGB         GetWindowLong( hWnd, 12 )
  73. #define    OTHERDATA             GetWindowWord( hWnd, 16 )
  74. #define    USENORMALTEXT         (GetWindowWord( hWnd, 18 ) & USENORMALTEXT_FLAG)
  75. #define    BUTTONISDOWN          (GetWindowWord( hWnd, 18 ) & BUTTONISDOWN_FLAG)
  76. #define    BUTTONINFOCUS         (GetWindowWord( hWnd, 18 ) & BUTTONINFOCUS_FLAG)
  77. #define    CAPTUREON             (GetWindowWord( hWnd, 18 ) & CAPTUREON_FLAG)
  78. #define    MKCNTLON              (GetWindowWord( hWnd, 18 ) & MKCNTLON_FLAG)
  79. #define    DRAWTEXTSTYLE         GetWindowWord( hWnd, 20 )
  80. #define    LABELFONT             GetWindowWord( hWnd, 22 )
  81.  
  82. #define    SET_FACEBRUSH(x)       SetWindowWord( hWnd, 0, x )
  83. #define    SET_SHADOWBRUSH(x)     SetWindowWord( hWnd, 2, x )
  84. #define    SET_HILITEBRUSH(x)     SetWindowWord( hWnd, 4, x )
  85. #define    SET_LABELRGN(x)        SetWindowWord( hWnd, 6, x )
  86. #define    SET_SHADOWRGN(x)       SetWindowWord( hWnd, 8, x )
  87. #define    SET_HILITERGN(x)       SetWindowWord( hWnd, 10, x )
  88. #define    SET_NORMALTEXTRGB(x)   SetWindowLong( hWnd, 12, x )
  89. #define    SET_OTHERDATA(x)       SetWindowWord( hWnd, 16, x )
  90.  
  91. #define    SET_USENORMALTEXT     SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) | USENORMALTEXT_FLAG) )
  92. #define    SET_USEGRAYEDTEXT     SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) & USEGRAYEDTEXT_FLAG) )
  93. #define    SET_BUTTONISDOWN      SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) | BUTTONISDOWN_FLAG) )
  94. #define    SET_BUTTONISUP        SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) & BUTTONISUP_FLAG) )
  95. #define    SET_BUTTONINFOCUS     SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) | BUTTONINFOCUS_FLAG) )
  96. #define    SET_BUTTONNOFOCUS     SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) & BUTTONNOFOCUS_FLAG) )
  97. #define    SET_CAPTUREON         SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) | CAPTUREON_FLAG) )
  98. #define    SET_CAPTUREOFF        SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) & CAPTUREOFF_FLAG) )
  99. #define    SET_MKCNTLON          SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) | MKCNTLON_FLAG) )
  100. #define    SET_MKCNTLOFF         SetWindowWord( hWnd, 18, (GetWindowWord ( hWnd, 18 ) & MKCNTLOFF_FLAG) )
  101.  
  102. #define    SET_DRAWTEXTSTYLE(x)  SetWindowWord( hWnd, 20, x )
  103. #define    SET_LABELFONT(x)      SetWindowWord( hWnd, 22, x )
  104.  
  105. /* ColorButton specific global variables */
  106.  
  107. HANDLE   hDrawTextWnd;
  108. HFONT    hDefLabelFont;         
  109. HPEN     hOutlinePen;
  110. HBRUSH   hDefFaceBrush, hDefHiliteBrush, hDefShadowBrush;
  111. COLORREF crDefNormalText;
  112. RECT     rDrawLabel;
  113. FARPROC  lpfnDrawLabel;
  114.  
  115. /* */
  116. /*
  117.  * LibMain( hInstance, wDataSegment, wHeapSize, lpszCmdLine ) : WORD
  118.  *
  119.  *    hInstance      library instance handle
  120.  *    wDataSegment   library data segment
  121.  *    wHeapSize      default heap size
  122.  *    lpszCmdLine    command line arguments
  123.  *
  124.  * LibMain is called by LibEntry, which is called by Windows when 
  125.  * the DLL is loaded.  The LibEntry routine is provided 
  126.  * in the LIBENTRY.OBJ in the SDK Link Libraries disk.  (The source 
  127.  * LIBENTRY.ASM is also provided.)  
  128.  *
  129.  * LibEntry initializes the DLL's heap, if a HEAPSIZE value is
  130.  * specified in the DLL's DEF file.  Then LibEntry calls
  131.  * LibMain.  The LibMain function below satisfies that call.
  132.  *
  133.  * LibMain performs all the initialization necessary to use the
  134.  * ColorButton user control.  Included in this initialization is the
  135.  * registration of the ColorButton window class.
  136.  *
  137. */
  138.  
  139. int FAR PASCAL LibMain( HANDLE      hInstance,
  140.                         WORD        wDataSegment,
  141.                         WORD        wHeapSize,
  142.                         LPSTR       lpszCmdLine )
  143. {
  144.    HANDLE               hClassStruct;
  145.    LPWNDCLASS           lpClassStruct;
  146.  
  147.    /* register ColorButton window if necessary */
  148.    if ( hLibInstance == NULL ) {
  149.  
  150.       /* allocate memory for class structure */
  151.       hClassStruct = GlobalAlloc( GHND, (DWORD)sizeof(WNDCLASS) );
  152.       if ( hClassStruct ) {
  153.  
  154.          /* lock it down */
  155.          lpClassStruct = (LPWNDCLASS)GlobalLock( hClassStruct );
  156.          if ( lpClassStruct ) {
  157.  
  158.             /* define class attributes */
  159.             lpClassStruct->lpszClassName = (LPSTR)COLORBUTTONCLASS;
  160.             lpClassStruct->hCursor =       LoadCursor( NULL, IDC_ARROW );
  161.             lpClassStruct->lpszMenuName =  (LPSTR)NULL;
  162.             lpClassStruct->style =         CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS|CS_GLOBALCLASS;
  163.             lpClassStruct->lpfnWndProc =   ColorButtonWndFn;
  164.             lpClassStruct->hInstance =     hInstance;
  165.             lpClassStruct->hIcon =         NULL;
  166.             lpClassStruct->cbWndExtra =    COLORBUTTON_EXTRA;
  167.             lpClassStruct->hbrBackground = (HBRUSH)(COLOR_WINDOW + 1 );
  168.    
  169.             /* register ColorButton window class */
  170.             hLibInstance = ( RegisterClass(lpClassStruct) ) ? hInstance : NULL;
  171.  
  172.             /* unlock structure */
  173.             GlobalUnlock( hClassStruct );
  174.          }
  175.          /* release class structure */
  176.          GlobalFree( hClassStruct );
  177.  
  178.       // Create default GDI object 
  179.  
  180.       // First the outline pen
  181.       hOutlinePen     = GetStockObject(BLACK_PEN);
  182.  
  183.       // Now default text color & font
  184.       crDefNormalText = GetSysColor(COLOR_BTNTEXT);
  185.       hDefLabelFont   = GetStockObject(SYSTEM_FONT);
  186.  
  187.       // Now default brushes 
  188.       hDefFaceBrush   = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
  189.       hDefShadowBrush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
  190.       hDefHiliteBrush = GetStockObject(WHITE_BRUSH);
  191.  
  192.       lpfnDrawLabel = MakeProcInstance(DrawLabel, hInstance);
  193.  
  194.       }
  195.    }
  196.    /* return result 1 = success; 0 = fail */
  197.    return( hLibInstance? 1:0 );
  198. }
  199.  
  200. /* */
  201. /****************************************************************************
  202.     FUNCTION:  WEP(int)
  203.  
  204.     PURPOSE:  Performs cleanup tasks when the DLL is unloaded.  WEP() is
  205.               called automatically by Windows when the DLL is unloaded
  206.               (no remaining tasks still have the DLL loaded).  It is
  207.               strongly recommended that a DLL have a WEP() function,
  208.               even if it does nothing but return, as in this example.
  209.  
  210. *******************************************************************************/
  211. VOID FAR PASCAL WEP (bSystemExit)
  212. int  bSystemExit;
  213. {
  214.     FreeProcInstance(lpfnDrawLabel);
  215.     DeleteObject(hDefFaceBrush);
  216.     DeleteObject(hDefShadowBrush);
  217.     return;
  218. }
  219.  
  220.  
  221. /* */
  222. /*
  223.  * ColorButtonInfo() : HANDLE
  224.  *
  225.  * This function returns a handle to a global block of memory that
  226.  * contains various information about the kinds of controls the library
  227.  * is capable of supporting.  This data block can, for example, be used
  228.  * by the dialog editor when determining the capabilities of a particular
  229.  * control library.
  230.  *
  231.  * Note that this handle becomes the property of the caller once this
  232.  * function returns.  This implies that the caller must call GlobalFree
  233.  * once it is finished with the data.
  234.  *
  235.  */
  236.  
  237. HANDLE FAR PASCAL ColorButtonInfo()
  238. {
  239.    HANDLE       hCtlInfo;
  240.    LPCTLINFO    lpCtlInfo;
  241.  
  242.    /* allocate space for information structure */
  243.    hCtlInfo = GlobalAlloc( GHND, (DWORD)sizeof(CTLINFO) );
  244.    if ( hCtlInfo ) {
  245.  
  246.       /* attempt to lock it down */
  247.       lpCtlInfo = (LPCTLINFO)GlobalLock( hCtlInfo );
  248.       if ( lpCtlInfo ) {
  249.  
  250.          /* define the fixed portion of the structure */
  251.          lpCtlInfo->wVersion = 100;
  252.          lpCtlInfo->wCtlTypes = 1;
  253.          lstrcpy( lpCtlInfo->szClass, COLORBUTTONCLASS );
  254.          lstrcpy( lpCtlInfo->szTitle, "Sample User Control" );
  255.  
  256.          /* define the variable portion of the structure */
  257.          lpCtlInfo->Type[0].wWidth = 25;
  258.          lpCtlInfo->Type[0].wHeight = 15;
  259.          lpCtlInfo->Type[0].dwStyle = WS_CHILD;
  260.          lstrcpy( lpCtlInfo->Type[0].szDescr, "ColorButton" );
  261.  
  262.          /* unlock it */
  263.          GlobalUnlock( hCtlInfo );
  264.       }
  265.       else {
  266.  
  267.          GlobalFree( hCtlInfo );
  268.          hCtlInfo = NULL;
  269.       }
  270.    }
  271.    /* return result */
  272.    return( hCtlInfo );
  273.  
  274. }
  275.  
  276. /* */
  277. /*
  278.  * ColorButtonStyle( hWnd, hCtlStyle, lpfnVeriyId, lpfnGetIdStr ) : BOOL;
  279.  *
  280.  *    hWnd           handle to parent window
  281.  *    hCtlStyle      handle to control style
  282.  *    lpfnVerifyId   pointer to the VerifyId function from Dialog editor
  283.  *    lpfnGetIdStr   pointer to the GetIdStr functionn from Dialog editor
  284.  *
  285.  * This function enables the user to edit the style of a particular
  286.  * control provided.  The current control style information is passed
  287.  * in using a handle to a control style data structure.
  288.  *
  289.  * This function returns this same handle (referencing updated
  290.  * information) if the dialog box is normally closed.  A value of
  291.  * NULL is returned if the user cancelled the operation.
  292.  *
  293.  */
  294.  
  295. BOOL FAR PASCAL ColorButtonStyle(HWND        hWnd,
  296.                                  HANDLE      hCtlStyle,
  297.                                  LPFNSTRTOID lpfnVerifyId,
  298.                                  LPFNIDTOSTR lpfnGetIdStr )
  299. {
  300.    FARPROC        lpDlgFn;
  301.    HANDLE        hNewCtlStyle;
  302.  
  303.    /* initialization */
  304.    hLibData  = hCtlStyle;
  305.    lpfnVerId = lpfnVerifyId;
  306.    lpfnIdStr = lpfnGetIdStr;
  307.  
  308.    /* display dialog box */
  309.    lpDlgFn = MakeProcInstance( (FARPROC)ColorButtonDlgFn, hLibInstance );
  310.    hNewCtlStyle = ( DialogBox(hLibInstance,"ColorButtonStyle",hWnd,lpDlgFn) ) ? hLibData : NULL;
  311.    FreeProcInstance( lpDlgFn );
  312.  
  313.    /* return updated data block */
  314.    return( hNewCtlStyle );
  315.  
  316. }
  317.  
  318. /* */
  319. /*
  320.  * ColorButtonFlags( wFlags, lpszString, wMaxString ) : WORD;
  321.  *
  322.  *    wFlags         class style flags
  323.  *    lpszString     class style string
  324.  *    wMaxString     maximum size of class style string
  325.  *
  326.  * This function translates the class style flags provided into a
  327.  * corresponding text string for output to an RC file.  The general
  328.  * windows flags (contained in the low byte) are not interpreted,
  329.  * only those in the high byte.
  330.  *
  331.  * The value returned by this function is the library instance
  332.  * handle when sucessful, and NULL otherwise.
  333.  *
  334.  */
  335.  
  336. WORD FAR PASCAL ColorButtonFlags(DWORD       dwFlags,
  337.                                  LPSTR       lpszString,
  338.                                  WORD        wMaxString )
  339. {
  340.  
  341.    if (LOWORD(dwFlags) & BS_DEFPUSHBUTTON) {
  342.       lstrcpy(lpszString, "BS_DEFPUSHBUTTON | WS_TABSTOP");
  343.       return( 29 );
  344.    }
  345.    else {
  346.       lstrcpy(lpszString, "WS_TABSTOP");
  347.       return( 10 );
  348.    }
  349. }
  350.  
  351. /* */
  352. /*
  353.  * ColorButtonWndFn( hWnd, wMsg, wParam, lParam ) : LONG
  354.  *
  355.  *        hWnd                    handle to ColorButton window
  356.  *        wMsg                    message number
  357.  *        wParam                  single word parameter
  358.  *        lParam                  double word parameter
  359.  *
  360.  * This function is responsible for processing all the messages
  361.  * which relate to the ColorButton control window.  Note how the
  362.  * code is written to avoid potential problems when re-entrancy
  363.  * ocurrs - this involves the use of extra bytes associated with
  364.  * the window data structure.
  365.  *
  366.  * The LONG value returned by this function is either a value
  367.  * returned by the internal handling of the message or by the
  368.  * default window procedure.
  369.  *
  370.  */
  371.  
  372. LONG FAR PASCAL ColorButtonWndFn(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam )
  373. {
  374.    /* local variables */
  375.    LONG  lResult;                    /* temporary result variable */
  376.     
  377.    /* initialization */
  378.    lResult = TRUE;
  379.     
  380.    /* process message */
  381.    switch( wMsg ) {
  382.  
  383.       case WM_CREATE:
  384.          // At this point we need to fill in the default extra bytes and 
  385.          // get the window name from the createstruct \
  386.          // In addition to window extra bytes each button control will be
  387.          // allocated local heap space to hold the label text and label 
  388.          // rectangle information.  A handle to this space is put into the
  389.          // window extra bytes.  Format for structure is as follows:
  390.          //   Label rect left int
  391.          //   Label rect top int
  392.          //   Label rect right int
  393.          //   Label rect bottom int
  394.          //   Label text len word
  395.          //   Label text [text len word] bytes
  396.          {
  397.             HANDLE hOtherData;
  398.             LPBYTE lpOtherData;
  399.             WORD   wTextLen, wAllocBytes;
  400.             LPCREATESTRUCT lpcsData;
  401.  
  402.             lpcsData = (LPCREATESTRUCT) lParam;
  403.             if ((lpcsData)->lpszName == NULL)
  404.                wTextLen = 0;
  405.             else
  406.                wTextLen = lstrlen((lpcsData)->lpszName);
  407.  
  408.             // allocate space for information structure 
  409.             wAllocBytes = wTextLen + LABEL_EXTRA_SPACE;
  410.             hOtherData = LocalAlloc( LHND, wAllocBytes );
  411.             if (hOtherData) {
  412.                if (wTextLen > 0) {
  413.  
  414.                   // attempt to lock it down 
  415.                   lpOtherData = (LPBYTE)LocalLock(hOtherData);
  416.                   if (lpOtherData) {
  417.    
  418.                      // Store button label text info in allocated structure
  419.                      lstrcpy((lpOtherData + LABEL_TEXT_OFFSET), (lpcsData)->lpszName);
  420.                      (WORD) *(lpOtherData + LABEL_LEN_OFFSET) = wTextLen;
  421.                      LocalUnlock(hOtherData);
  422.                   }
  423.                }
  424.                // Store handle to structure, default brushes and colors
  425.                SET_OTHERDATA(hOtherData);
  426.                SET_FACEBRUSH(hDefFaceBrush);
  427.                SET_SHADOWBRUSH(hDefShadowBrush);
  428.                SET_HILITEBRUSH(hDefHiliteBrush);
  429.                SET_NORMALTEXTRGB(crDefNormalText);
  430.                SET_LABELFONT(hDefLabelFont);
  431.                SET_USENORMALTEXT;
  432.                SET_BUTTONISUP;
  433.                SET_BUTTONNOFOCUS;
  434.                SET_MKCNTLOFF;
  435.                SET_CAPTUREOFF;
  436.                SET_DRAWTEXTSTYLE((DT_CENTER | DT_WORDBREAK));
  437.  
  438.                SET_HILITERGN(NULL);
  439.                SET_SHADOWRGN(NULL);
  440.                SET_LABELRGN(NULL);
  441.  
  442.             //else post an error
  443.             }
  444.          //else post an error
  445.          }
  446.          break;
  447.  
  448.       case WM_GETDLGCODE:
  449.          {
  450.             if (GetWindowLong(hWnd, GWL_STYLE) & BS_DEFPUSHBUTTON)
  451.                lResult = (LONG) DLGC_DEFPUSHBUTTON;
  452.             else
  453.                lResult = (LONG) DLGC_UNDEFPUSHBUTTON;
  454.          }
  455.          break;
  456.  
  457.       case WM_SIZE:
  458.          // At this point we need to fill in the default extra bytes and 
  459.          {
  460.             POINT pts[6];
  461.             int iLblHi, iLblWi, iTxtMaxWi, iTxtMaxHi;
  462.             RECT rRect;
  463.             LPRECT lprLabel;
  464.             LPBYTE lpLabelText;
  465.             HDC hDC;
  466.             HRGN hHiliteRgn, hShadowRgn, hLabelRgn;
  467.             HFONT hOldFont;
  468.  
  469.             hHiliteRgn = HILITERGN;
  470.             hShadowRgn = SHADOWRGN;
  471.             hLabelRgn  = LABELRGN;
  472.  
  473.             if (hHiliteRgn)
  474.                DeleteObject(hHiliteRgn);
  475.             if (hHiliteRgn)
  476.                DeleteObject(hShadowRgn);
  477.             if (hHiliteRgn)
  478.                DeleteObject(hLabelRgn);
  479.  
  480.             lprLabel = (LPRECT) LocalLock(OTHERDATA);
  481.  
  482.             hDC = GetDC(hWnd);
  483.  
  484.             hOldFont = SelectObject(hDC, LABELFONT);
  485.             GetClientRect(hWnd, &rRect);
  486.  
  487.             // Create the hilite region
  488.             pts[0].x = pts[1].x = pts[1].y = pts[2].y = 1;
  489.             pts[4].x = pts[5].x = pts[3].y = pts[4].y = 3;
  490.             pts[0].y = rRect.bottom - 2;
  491.             pts[2].x = rRect.right - 2;
  492.             pts[3].x = rRect.right - 4;
  493.             pts[5].y = rRect.bottom - 4;
  494.             hHiliteRgn = CreatePolygonRgn((LPPOINT)&pts, 6, WINDING);
  495.             SET_HILITERGN(hHiliteRgn);
  496.  
  497.             // Create the shadow region
  498.             pts[4].x = pts[5].x = rRect.right - 3;
  499.             pts[3].x = pts[5].y = 2;
  500.             pts[2].x = pts[0].y = 0;
  501.             pts[3].y = pts[4].y = rRect.bottom - 3;
  502.             pts[1].x = pts[0].x = rRect.right - 1;
  503.             pts[1].y = pts[2].y = rRect.bottom - 1;
  504.             hShadowRgn = CreatePolygonRgn((LPPOINT)&pts, 6, WINDING);
  505.             SET_SHADOWRGN(hShadowRgn);
  506.  
  507.         // max size for label area is:
  508.             (lprLabel)->left   = 6;
  509.             (lprLabel)->top    = 6;
  510.             (lprLabel)->bottom = rRect.bottom - 6;
  511.             (lprLabel)->right  = rRect.right - 6;
  512.         // Now test for minimum height of rectangle
  513.             lpLabelText = (LPBYTE) (lprLabel) + LABEL_TEXT_OFFSET;
  514.             if (!(lpLabelText[0] == NULL)) 
  515.                DrawText(hDC, lpLabelText, -1, lprLabel, ((DRAWTEXTSTYLE) | DT_CALCRECT));
  516.         // Make sure label rect does not exceed max size
  517.             iTxtMaxHi = rRect.bottom - 12;
  518.             iTxtMaxWi = rRect.right - 12;
  519.             iLblHi    = (lprLabel)->bottom - (lprLabel)->top;
  520.             if (iLblHi > iTxtMaxHi) 
  521.                iLblHi = iTxtMaxHi;
  522.             iLblWi    = (lprLabel)->right - (lprLabel)->left;
  523.             if (iLblWi > iTxtMaxWi) 
  524.                iLblWi = iTxtMaxWi;
  525.         // Reset label rect to center vertically
  526.             (lprLabel)->left   = ((iTxtMaxWi - iLblWi) / 2) + 6;
  527.             (lprLabel)->top    = ((iTxtMaxHi - iLblHi) / 2) + 6;
  528.             (lprLabel)->right  = (lprLabel)->left + iLblWi;
  529.             (lprLabel)->bottom = (lprLabel)->top + iLblHi;
  530.             hLabelRgn = CreateRectRgn((lprLabel)->left,
  531.                                       (lprLabel)->top, 
  532.                                       (lprLabel)->right, 
  533.                                       (lprLabel)->bottom);
  534.             SET_LABELRGN(hLabelRgn);
  535.             SelectObject(hDC, hOldFont);
  536.             LocalUnlock(OTHERDATA);
  537.             ReleaseDC(hWnd, hDC);
  538.          }
  539.          break;
  540.  
  541.       case WM_PAINT:
  542.          {
  543.             PAINTSTRUCT ps;
  544.             RECT rRect;
  545.             LPRECT lprLabel;
  546.             LPBYTE lpLabelText;
  547.             WORD wTextLen;
  548.             HDC  hDC;
  549.             HPEN hOldPen;
  550.             HBRUSH hOldBrush;
  551.             HFONT hOldFont;
  552.  
  553.             hDC = BeginPaint(hWnd, &ps);
  554.  
  555.             // Before painting anything, notify parent to provide opportunity
  556.             // to set new brush and text colors (like pushbutton, nothing is
  557.             // is done with the return value.                                     
  558.             SendMessage(PARENT, WM_CTLCOLOR, hDC, MAKELONG(hWnd, CTLCOLOR_BTN));
  559.  
  560.             lprLabel = (LPRECT) LocalLock(OTHERDATA);
  561.             GetClientRect(hWnd, &rRect);
  562.  
  563.             // Set text color and font
  564.             SetTextColor(hDC, NORMALTEXTRGB);
  565.             SetBkMode(hDC, TRANSPARENT);
  566.             hOldFont = SelectObject(hDC, (HFONT) LABELFONT);
  567.  
  568.             // Create Button Outline and Fill with Face color
  569.             hOldPen = SelectObject(hDC, hOutlinePen);
  570.             hOldBrush = SelectObject(hDC, FACEBRUSH);
  571.             RoundRect(hDC, rRect.left, rRect.top, rRect.right, rRect.bottom, 2, 2);
  572.             // Create button hilite & shadow
  573.             if (BUTTONISDOWN) {
  574.                FillRgn(hDC, HILITERGN, SHADOWBRUSH);
  575.                FillRgn(hDC, SHADOWRGN, FACEBRUSH);
  576.             }
  577.             else {
  578.                FillRgn(hDC, HILITERGN, HILITEBRUSH);
  579.                FillRgn(hDC, SHADOWRGN, SHADOWBRUSH);
  580.             }
  581.             // Display Label text
  582.             lpLabelText = (LPBYTE) (lprLabel) + LABEL_TEXT_OFFSET;
  583.             wTextLen =  (WORD) *((LPBYTE) (lprLabel) + LABEL_LEN_OFFSET);
  584.             // When paint button in down position shift the label rect
  585.             if (BUTTONISDOWN)
  586.                OffsetRect(lprLabel, 2, 2);
  587.             if (!(lpLabelText[0] == NULL)) {
  588.                if (USENORMALTEXT) {
  589.                   DrawText(hDC, lpLabelText, -1, lprLabel, DRAWTEXTSTYLE);
  590.                }
  591.                else {
  592.                   HBRUSH hGrayedTextBrush;
  593.                   POINT pt;
  594.  
  595.                   hGrayedTextBrush = CreateSolidBrush(NORMALTEXTRGB);
  596.                   pt.x = pt.y = 0;
  597.                   ClientToScreen(hWnd, &pt);
  598.                   UnrealizeObject(hGrayedTextBrush);
  599.                   SetBrushOrg(hDC, pt.x, pt.y);
  600.  
  601.                   hDrawTextWnd = hWnd;
  602.                   rDrawLabel.left = rDrawLabel.top = 0;
  603.                   rDrawLabel.right = (lprLabel)->right - (lprLabel)->left;
  604.                   rDrawLabel.bottom = (lprLabel)->bottom - (lprLabel)->top;
  605.                   GrayString(hDC, hGrayedTextBrush, lpfnDrawLabel, 
  606.                              (DWORD) lpLabelText, wTextLen, 
  607.                              (lprLabel)->left, (lprLabel)->top, 
  608.                              (lprLabel)->right - (lprLabel)->left, 
  609.                              (lprLabel)->bottom - (lprLabel)->top);
  610.                   DeleteObject(hGrayedTextBrush);
  611.                }
  612.             }
  613.  
  614.             if (BUTTONINFOCUS) {
  615.                rRect.left   =  (lprLabel)->left - 2;
  616.                rRect.top    =  (lprLabel)->top - 2; 
  617.                rRect.right  =  (lprLabel)->right + 2;
  618.                rRect.bottom =  (lprLabel)->bottom + 2;
  619.                DrawFocusRect(hDC, &rRect);
  620.             }
  621.  
  622.             // After paint button in down position reset label rect value
  623.             if (BUTTONISDOWN)
  624.                OffsetRect(lprLabel, -2, -2);
  625.  
  626.             SelectObject(hDC, hOldPen);
  627.             SelectObject(hDC, hOldBrush);
  628.             SelectObject(hDC, hOldFont);
  629.  
  630.             LocalUnlock(OTHERDATA);
  631.             EndPaint(hWnd, &ps);
  632.          }
  633.          break;
  634.  
  635.       case WM_SETFOCUS:
  636.          {
  637.             SET_BUTTONINFOCUS;
  638.             InvalidateRect(hWnd, NULL, FALSE);
  639.          }
  640.          break;
  641.       case WM_KILLFOCUS:
  642.          {
  643.             SET_BUTTONNOFOCUS;
  644.             InvalidateRect(hWnd, NULL, FALSE);
  645.             UpdateWindow(hWnd);
  646.          }
  647.          break;
  648.  
  649.       case WM_ENABLE:
  650.          {
  651.             if (wParam)   {
  652.                SET_USENORMALTEXT;
  653.             }
  654.             else {
  655.                SET_USEGRAYEDTEXT;
  656.             }
  657.             InvalidateRect(hWnd, NULL, FALSE);
  658.             UpdateWindow(hWnd);
  659.          }
  660.          break;
  661.  
  662.       case WM_KEYDOWN:
  663.          {
  664.             if (wParam == VK_SPACE) {
  665.                // if mouse does not have control
  666.                if (!(MKCNTLON)) {
  667.                   //if the button is shown in the up position
  668.                   if (!(BUTTONISDOWN)) {
  669.                      ShowButtonDown(hWnd);
  670.                   }
  671.                }
  672.             }
  673.          }
  674.          break;
  675.  
  676.       case WM_LBUTTONDBLCLK:
  677.       case WM_LBUTTONDOWN:
  678.          {
  679.             if (!(CAPTUREON)) {
  680.                SET_CAPTUREON;
  681.                SetCapture(hWnd);
  682.                SET_MKCNTLON;
  683.  
  684.                if (!(BUTTONISDOWN)) 
  685.                   ShowButtonDown(hWnd);
  686.             }
  687.          }
  688.          break;
  689.  
  690.       case WM_KEYUP:
  691.          {
  692.             if (wParam == VK_SPACE) {
  693.  
  694.                // if mouse does not have control
  695.                if (!(MKCNTLON)) {
  696.  
  697.                   //if the button is shown in the down position
  698.                   if ((BUTTONISDOWN)) {
  699.  
  700.                      ShowButtonUp(hWnd);
  701.  
  702.                      // send the parent window a button clicked command message
  703.                      SendMessage(PARENT,WM_COMMAND,ID,MAKELONG(hWnd, BN_CLICKED));
  704.                   }
  705.                }
  706.             }
  707.          }
  708.          break;
  709.  
  710.       case WM_LBUTTONUP:
  711.          {
  712.  
  713.             if (CAPTUREON) {
  714.                RECT rRect;
  715.  
  716.                GetClientRect(hWnd, &rRect);
  717.                if (PtInRect(&rRect, MAKEPOINT(lParam)))  {
  718.  
  719.                   // send the parent window a button clicked command message
  720.                   SendMessage(PARENT,WM_COMMAND,ID,MAKELONG(hWnd, BN_CLICKED));
  721.                   ShowButtonUp(hWnd);
  722.                }
  723.                SET_MKCNTLOFF;
  724.                SET_CAPTUREOFF;
  725.                ReleaseCapture();
  726.             }
  727.          }
  728.          break;
  729.  
  730.       case WM_MOUSEACTIVATE:
  731.          {
  732.             SetFocus(hWnd);
  733.          }
  734.          break;
  735.  
  736.       case WM_MOUSEMOVE:
  737.          {
  738.             RECT rRect;
  739.  
  740.             GetClientRect(hWnd, &rRect);
  741.  
  742.             // is the cursor in the button window
  743.             if (PtInRect(&rRect, MAKEPOINT(lParam)))  {
  744.  
  745.                // is the mouse button down
  746.                if (wParam & MK_LBUTTON) {
  747.  
  748.                   // is the button shown in the up position?
  749.                   if (!(BUTTONISDOWN)) {
  750.  
  751.                      SET_BUTTONISDOWN;
  752.                      InvalidateRect(hWnd, NULL, FALSE);
  753.                      UpdateWindow(hWnd);
  754.                   }
  755.                }
  756.             }
  757.             else {    //cursor outside of the button window
  758.  
  759.                // is the mouse button down
  760.                if (wParam & MK_LBUTTON) {
  761.  
  762.                   // is the button shown in the down position 
  763.                   if (BUTTONISDOWN) {
  764.  
  765.                      SET_BUTTONISUP;
  766.                      InvalidateRect(hWnd, NULL, FALSE);
  767.                      UpdateWindow(hWnd);
  768.                   }
  769.                }
  770.             }
  771.          }
  772.          break;
  773.  
  774.       case WM_SETTEXT:
  775.          {
  776.             WORD wNewTextLen, wCurrSize;
  777.             LPBYTE lpOtherData;
  778.             HANDLE hOtherData;
  779.             RECT rRect;
  780.             WORD wHi, wWi;
  781.  
  782.             if (lParam == NULL)
  783.                wNewTextLen = 0;
  784.             else
  785.                wNewTextLen = lstrlen((LPSTR) lParam);
  786.  
  787.             wCurrSize =  LocalSize(OTHERDATA);
  788.  
  789.             // If the new label string is larger than space currently allocated,
  790.             // then realloc more space
  791.             if ((wNewTextLen + LABEL_EXTRA_SPACE) > wCurrSize) {
  792.                hOtherData = LocalReAlloc(OTHERDATA, 
  793.                                          (wNewTextLen + LABEL_EXTRA_SPACE),
  794.                                          LHND);
  795.                if (hOtherData) 
  796.                   SET_OTHERDATA(hOtherData);
  797.                else {
  798.                   lResult = FALSE;
  799.                   break;
  800.                }
  801.             }
  802.  
  803.             lpOtherData = (LPBYTE)LocalLock(OTHERDATA);
  804.             if (lpOtherData) {
  805.  
  806.                // Store button label text info in allocated structure
  807.                if (wNewTextLen)
  808.                   lstrcpy((lpOtherData + LABEL_TEXT_OFFSET), (LPSTR) lParam);
  809.                else
  810.                   *(lpOtherData + LABEL_TEXT_OFFSET) = NULL;
  811.  
  812.                (WORD) *(lpOtherData + LABEL_LEN_OFFSET) = wNewTextLen;
  813.                LocalUnlock(OTHERDATA);
  814.  
  815.                GetClientRect(hWnd, &rRect);
  816.                wHi = rRect.bottom - rRect.top;
  817.                wWi = rRect.right - rRect.left;
  818.                SendMessage(hWnd,WM_SIZE,SIZENORMAL,MAKELONG(wWi,wHi));
  819.  
  820.             }
  821.          }
  822.          break;
  823.  
  824.       case WM_GETTEXTLENGTH:
  825.          {
  826.             LPBYTE lpOtherData;
  827.             WORD wTextLen;
  828.  
  829.             lpOtherData = (LPBYTE) LocalLock(OTHERDATA);
  830.             wTextLen = (WORD) *(lpOtherData + LABEL_LEN_OFFSET);
  831.             lResult = (LONG) wTextLen;
  832.             LocalUnlock(OTHERDATA);
  833.          }
  834.          break;
  835.  
  836.       case WM_GETTEXT:
  837.          {
  838.             LPBYTE lpOtherData;
  839.             WORD wTextLen;
  840.  
  841.             lpOtherData = (LPBYTE) LocalLock(OTHERDATA);
  842.             wTextLen = (int) *(lpOtherData + LABEL_LEN_OFFSET);
  843.             if (wParam < wTextLen)
  844.                wTextLen = wParam;
  845.             if (wTextLen > 0)
  846.                lstrncpy( (LPSTR) lParam, (lpOtherData + LABEL_TEXT_OFFSET), (int) wTextLen);
  847.             lResult = (LONG) wTextLen;
  848.             LocalUnlock(OTHERDATA);
  849.          }
  850.          break;
  851.  
  852.       case WM_CLOSE:
  853.          {
  854.             DeleteObject(HILITERGN);
  855.             DeleteObject(SHADOWRGN);
  856.             DeleteObject(LABELRGN);
  857.             LocalFree(OTHERDATA);
  858.             lResult = DefWindowProc( hWnd, wMsg, wParam, lParam );
  859.          }
  860.          break;
  861.  
  862.       case CRBM_SETFACEBRUSH:
  863.          {
  864.             if (wParam)
  865.                SET_FACEBRUSH(wParam);
  866.             else
  867.                SET_FACEBRUSH(hDefFaceBrush);
  868.          }
  869.          break;
  870.  
  871.       case CRBM_SETSHADOWBRUSH:
  872.          {
  873.             if (wParam)
  874.                SET_SHADOWBRUSH(wParam);
  875.             else
  876.                SET_SHADOWBRUSH(hDefShadowBrush);
  877.          }
  878.          break;
  879.  
  880.       case CRBM_SETTEXTCOLOR:
  881.          {
  882.             if (wParam)
  883.                SET_NORMALTEXTRGB(lParam);
  884.             else
  885.                SET_NORMALTEXTRGB(crDefNormalText);
  886.          }
  887.          break;
  888.  
  889.       case CRBM_SETDRAWTEXTSTYLE:
  890.          {
  891.             SET_DRAWTEXTSTYLE(wParam & STRIP_BAD_DT_FLAG);
  892.          }
  893.          break;
  894.  
  895.       case WM_SETFONT:
  896.       case CRBM_SETLABELFONT:
  897.          {
  898.             RECT rRect;
  899.             WORD wHi, wWi;
  900.  
  901.             if (wParam)
  902.                SET_LABELFONT(wParam);
  903.             else
  904.                SET_LABELFONT(hDefLabelFont);
  905.  
  906.             GetClientRect(hWnd, &rRect);
  907.             wHi = rRect.bottom - rRect.top;
  908.             wWi = rRect.right - rRect.left;
  909.             SendMessage(hWnd,WM_SIZE,SIZENORMAL,MAKELONG(wWi,wHi));
  910.          }
  911.          break;
  912.  
  913.       case CRBM_GETFACEBRUSH:
  914.          {
  915.             HBRUSH hTmpBrush;
  916.  
  917.             hTmpBrush = (HBRUSH) FACEBRUSH;
  918.             if (hTmpBrush == hDefFaceBrush)
  919.                hTmpBrush = NULL;
  920.             lResult = MAKELONG (hTmpBrush, 0);
  921.          }
  922.          break;
  923.  
  924.       case CRBM_GETSHADOWBRUSH:
  925.          {
  926.             HBRUSH hTmpBrush;
  927.  
  928.             hTmpBrush = (HBRUSH) SHADOWBRUSH;
  929.             if (hTmpBrush == hDefShadowBrush)
  930.                hTmpBrush = NULL;
  931.             lResult = MAKELONG (hTmpBrush, 0);
  932.          }
  933.          break;
  934.  
  935.       case CRBM_GETTEXTCOLOR:
  936.          {
  937.             lResult = NORMALTEXTRGB;
  938.          }
  939.          break;
  940.  
  941.       case CRBM_GETDRAWTEXTSTYLE:
  942.          {
  943.             lResult = MAKELONG (DRAWTEXTSTYLE, 0);
  944.          }
  945.  
  946.       case WM_GETFONT:
  947.       case CRBM_GETLABELFONT:
  948.          {
  949.             HFONT hTmpFont;
  950.  
  951.             hTmpFont = (HFONT) LABELFONT;
  952.             if (hTmpFont == hDefLabelFont)
  953.                hTmpFont = NULL;
  954.             lResult = MAKELONG (hTmpFont, 0);
  955.          }
  956.          break;
  957.  
  958.       default : /* default window message processing */
  959.          lResult = DefWindowProc( hWnd, wMsg, wParam, lParam );
  960.          break;
  961.     }
  962.     
  963.     /* return final result */
  964.     return( lResult );
  965.  
  966. }
  967.  
  968. /* */
  969. /*
  970.  * ColorButtonDlgFn( hDlg, wMessage, wParam, lParam ) : BOOL;
  971.  *
  972.  *    hDlg           dialog box handle
  973.  *    wMessage       current window message
  974.  *    wParam         word parameter
  975.  *    lParam         long parameter
  976.  *
  977.  * This function is responsible for processing all the messages that
  978.  * relate to the style dialog box.  This function transfers data 
  979.  * between itself and the ColorButtonStyle using a global data handle.
  980.  *
  981.  * If the user presses the OK button, this data handle is used to pass
  982.  * back a new style data block.  It is left to the calling routine to
  983.  * delete this new block.
  984.  *
  985.  */
  986.  
  987. BOOL FAR PASCAL ColorButtonDlgFn(HWND        hDlg,
  988.                                  WORD        wMessage,
  989.                                  WORD        wParam,
  990.                                  LONG        lParam )
  991. {
  992.    BOOL            bResult;
  993.  
  994.    /* initialization */
  995.    bResult = TRUE;
  996.  
  997.    /* process message */
  998.    switch( wMessage )  {
  999.  
  1000.       case WM_INITDIALOG :
  1001.          { 
  1002.             HANDLE        hCtlStyle;
  1003.             LPCTLSTYLE    lpCtlStyle;
  1004.             char          szId[  20 ];    /* temp. string to hold id */
  1005.    
  1006.             /* disable Ok button & save dialog data handle */
  1007.             hCtlStyle = hLibData;
  1008.             EnableWindow( GetDlgItem(hDlg,IDOK), FALSE );
  1009.    
  1010.             /* retrieve & display style parameters */
  1011.             if ( hCtlStyle ) {
  1012.                
  1013.                /* add handle to property list */
  1014.                SetProp( hDlg, MAKEINTRESOURCE(1), hCtlStyle );
  1015.                
  1016.                /* update dialog box fields */
  1017.                lpCtlStyle = (LPCTLSTYLE)GlobalLock( hCtlStyle );
  1018.                SetDlgItemText( hDlg, IDTEXT, lpCtlStyle->szTitle );
  1019.    
  1020.                /* Set the id value string correctly.
  1021.                 * Save the pointer to the verify id function from dialog editor
  1022.                 */
  1023.                if ( lpfnIdStr )
  1024.                {
  1025.                   (*lpfnIdStr)(lpCtlStyle->wId, (LPSTR)szId, sizeof( szId ) );
  1026.                   SetDlgItemText( hDlg, IDVALUE, szId );
  1027.                }
  1028.                else {
  1029.                   EnableWindow( GetDlgItem( hDlg, IDVALUE ), FALSE );
  1030.                }
  1031.  
  1032.                CheckDlgButton(hDlg, 258, (WORD) (LOWORD(lpCtlStyle->dwStyle) & BS_DEFPUSHBUTTON));
  1033.  
  1034.                lstrcpy( lpCtlStyle->szClass, COLORBUTTONCLASS );
  1035.                SetProp( hDlg, IDFNHI, HIWORD( (DWORD)lpfnVerId ) );
  1036.                SetProp( hDlg, IDFNLO, LOWORD( (DWORD)lpfnVerId ) );
  1037.                GlobalUnlock( hCtlStyle );
  1038.             }
  1039.             else
  1040.                EndDialog( hDlg, FALSE );
  1041.          }
  1042.          break;
  1043.  
  1044.       case WM_COMMAND :
  1045.  
  1046.        /* process sub-message */
  1047.          switch( wParam ) {
  1048.             case IDCANCEL : /* cancel dialog box */
  1049.                RemoveProp( hDlg, MAKEINTRESOURCE(1) );
  1050.                RemoveProp( hDlg, IDFNLO );
  1051.                RemoveProp( hDlg, IDFNHI );
  1052.                EndDialog( hDlg, FALSE );
  1053.                break;
  1054.  
  1055.             case IDOK :    /* save dialog changes */
  1056.                {
  1057.                   HANDLE           hCtlStyle;
  1058.                   LPCTLSTYLE       lpCtlStyle;
  1059.                   LPFNSTRTOID      lpfnId;          /* pointer to the verify id function from dialog editor */
  1060.                   char             szId[ 20 ];        /* temp. string to hold the id */
  1061.         
  1062.                   hCtlStyle = GetProp( hDlg, MAKEINTRESOURCE(1) );
  1063.         
  1064.                   /* update structure contents */
  1065.                   lpCtlStyle = (LPCTLSTYLE)GlobalLock( hCtlStyle );
  1066.         
  1067.                   szId[ 0 ] = NULL;
  1068.                   GetDlgItemText( hDlg, IDVALUE, szId, sizeof(szId) );
  1069.                   lpfnId = (LPFNSTRTOID)MAKELONG( GetProp( hDlg, IDFNLO ), GetProp( hDlg, IDFNHI ) );
  1070.                   if ( lpfnId ) {
  1071.                      DWORD        dwResult; /* result ofthe verifyId function */
  1072.         
  1073.                      dwResult = (*lpfnId)( (LPSTR)szId );
  1074.                      if ( !(BOOL)dwResult ) {
  1075.                         /* Wrong id */
  1076.                         GlobalUnlock( hCtlStyle );
  1077.                         break;        
  1078.                       }
  1079.                       lpCtlStyle->wId = HIWORD( dwResult );
  1080.                       if (IsDlgButtonChecked(hDlg, 258))
  1081.                          lpCtlStyle->dwStyle |= BS_DEFPUSHBUTTON;
  1082.                       else
  1083.                          lpCtlStyle->dwStyle |= BS_PUSHBUTTON;
  1084.  
  1085.                   }
  1086.                   GetDlgItemText( hDlg, IDTEXT, lpCtlStyle->szTitle, sizeof(lpCtlStyle->szTitle) );
  1087.                   GlobalUnlock( hCtlStyle );
  1088.                   RemoveProp( hDlg, MAKEINTRESOURCE(1) );
  1089.                   RemoveProp( hDlg, IDFNLO );
  1090.                   RemoveProp( hDlg, IDFNHI );
  1091.                   
  1092.                   /* end dialog box */
  1093.                   hLibData = hCtlStyle;
  1094.                   EndDialog( hDlg, TRUE );
  1095.                }
  1096.                break;
  1097.  
  1098.             case IDTEXT : /* control text */
  1099.             case IDVALUE : /* control id */
  1100.      
  1101.                /* enable or disable Ok button */
  1102.                if ( HIWORD(lParam) == EN_CHANGE )
  1103.                   EnableWindow(GetDlgItem(hDlg,IDOK),
  1104.                               (SendMessage(GetDlgItem(hDlg,IDTEXT),WM_GETTEXTLENGTH,0,0L) &&
  1105.                                SendMessage(GetDlgItem(hDlg,IDVALUE),WM_GETTEXTLENGTH,0,0L)) ? 
  1106.                                TRUE : FALSE);
  1107.                break;
  1108.  
  1109.             default : /* something else */
  1110.                bResult = FALSE;
  1111.                break;
  1112.          }
  1113.          break;
  1114.  
  1115.       default :
  1116.          bResult = FALSE;
  1117.          break;
  1118.    }
  1119.    /* return final result */
  1120.    return( bResult );
  1121. }
  1122.  
  1123. /* */
  1124.  
  1125. void ShowButtonDown(HANDLE hWnd)
  1126. {
  1127.    SET_BUTTONISDOWN;
  1128.    InvalidateRect(hWnd, NULL, FALSE);
  1129.    UpdateWindow(hWnd);
  1130. }
  1131.  
  1132. void ShowButtonUp(HANDLE hWnd)
  1133. {
  1134.    SET_BUTTONISUP;
  1135.    InvalidateRect(hWnd, NULL, FALSE);
  1136.    UpdateWindow(hWnd);
  1137. }
  1138.  
  1139. BOOL FAR PASCAL DrawLabel(HDC hDC, LPSTR lpLabelText, int nCount)
  1140. {
  1141.    HANDLE hWnd;
  1142.  
  1143.    hWnd = hDrawTextWnd;
  1144.    DrawText(hDC, lpLabelText, nCount, &rDrawLabel, DRAWTEXTSTYLE);
  1145.    return(TRUE);
  1146. }
  1147.  
  1148. void lstrncpy(LPSTR lpDest, LPSTR lpSrc, int n)
  1149. {
  1150.     while (n--)
  1151.         if(!(*lpDest++ = *lpSrc++))
  1152.             return;
  1153. }
  1154.  
  1155.